use anyhow::{Result,anyhow};
use serde_json;
use chrono::{DateTime, Utc, Duration};
use webrtc::rtp_transceiver::rtp_codec::RTCRtpCodecParameters;
use std::str::FromStr;
use std::u8;
use serde::{Serialize, Deserialize};
use reqwest::Client;
use crate::db::{db_select::db_select, db_insert::db_insert};
use crate::api::get_xsts::get_xsts_stream_token;
use serde_json::Value;
use webrtc::api::media_engine::*;
use webrtc::rtp_transceiver::rtp_codec::{RTCRtpCodecCapability};
use webrtc::rtp_transceiver::rtp_codec::RTPCodecType;
use webrtc::peer_connection::RTCPeerConnection;
use webrtc::peer_connection::configuration::RTCConfiguration;
use webrtc::api::APIBuilder;
use webrtc::rtp_transceiver::{RTCRtpTransceiverInit, rtp_transceiver_direction::RTCRtpTransceiverDirection};
use webrtc::ice_transport::ice_server::RTCIceServer;
use webrtc::data_channel::data_channel_init::RTCDataChannelInit;
use webrtc::api::media_engine::MediaEngine;
use crate::api::send_sdp::send_sdp;
use crate::web_rtc::divide_audio_video::divide_audio_video;
use tokio::time::{sleep, Duration as TokioDuration};
use crate::api::get_sdp::get_sdp;
use webrtc::peer_connection::sdp::session_description::RTCSessionDescription;
use webrtc::ice_transport::ice_candidate::RTCIceCandidate;
use std::sync::{Arc};
use tokio::sync::Mutex;
use crate::api::send_ice::send_ice;
use crate::api::get_session_status::get_session_status;
use crate::api::get_ice::get_ice;
use super::turn::TurnServerConfig;
use crate::media::media_ctrl;
use super::channel::{message_channel::message_channel_init, control_channel::control_channel_init, input_channel::input_channel_init, chat_channel};
use once_cell::sync::Lazy;
use crate::web_rtc::code_rate;
use crate::web_rtc::check_status;
use super::divide_audio_video::check_tracks_status;
use super::channel::input_channel::INPUT_CHANNEL_STATUS;
use super::channel::control_channel::CONTROL_CHANNEL_STATUS;
use std::sync::atomic::Ordering;
use super::close::close_by_xbox_init;

// WebRTC init
pub static PEER_CONNECTION: Lazy<Arc<Mutex<Option<RTCPeerConnection>>>> = Lazy::new(|| {
    Arc::new(Mutex::new(None))
});

pub async fn init() -> Result<()> {
    // 等待主机就绪
    get_session_status().await.unwrap();

    // 设置stun和turn服务器(turn服务器暂未实现)
    let mut ice_servers = Vec::<RTCIceServer>::new();
    ice_servers = [
        RTCIceServer {
            urls: vec!["stun:stun.l.google.com:19302".to_string()],
            ..Default::default()
        },
        RTCIceServer {
            urls: vec!["stun:stun.services.mozilla.com:3478".to_string()],
            ..Default::default()
        },
        RTCIceServer {
            urls: vec!["stun:stun.miwifi.com:3478".to_string()],
            ..Default::default()
        },
        RTCIceServer {
            urls: vec!["stun:stun.chat.bilibili.com:3478".to_string()],
            ..Default::default()
        },
        RTCIceServer {
            urls: vec!["stun:stun.cloudflare.com:3478".to_string()],
            ..Default::default()
        },
        RTCIceServer {
            urls: vec!["stun:stun.qq.com:3478".to_string()],
            ..Default::default()
        },
        // RTCIceServer {
        //     urls: vec!["turn:turn.cloudflare.com:3478".to_string()],
        //     ..Default::default()
        // },
        RTCIceServer {
            urls: vec!["stun:stun.nextcloud.com:3478".to_string()],
            ..Default::default()
        }
    ].to_vec();
    // 若有turn服务器配置，则添加turn服务器
    if let Some(turn_server) = TurnServerConfig::get().await {
        // 检查URL是否包含协议前缀，如果没有则添加
        let full_url = if turn_server.server.starts_with("turn:") || turn_server.server.starts_with("turns:") {
            turn_server.server
        } else {
            format!("turn:{}", turn_server.server)
        };

        ice_servers.push(
            RTCIceServer {
                urls: vec![full_url],
                username: turn_server.username,
                credential: turn_server.password,
            }
        );
    }


    // 设置默认的支持的解码器
    let mut media_engine = MediaEngine::default();
    // 注册音频：Opus
    media_engine.register_codec(
        RTCRtpCodecParameters {
            capability: RTCRtpCodecCapability {
                mime_type: MIME_TYPE_OPUS.to_owned(),
                clock_rate: 48000,
                channels: 2,
                sdp_fmtp_line: "".to_owned(),
                rtcp_feedback: vec![],
            },
            payload_type: 111,
            ..Default::default()
        },
        RTPCodecType::Audio,
    )?;

    // 注册视频：H264-low
    media_engine.register_codec(
        RTCRtpCodecParameters {
            capability: RTCRtpCodecCapability {
                mime_type: MIME_TYPE_H264.to_owned(),
                clock_rate: 90000,
                channels: 0,
                sdp_fmtp_line: "profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1".to_owned(),
                rtcp_feedback: vec![],
            },
            payload_type: 102,
            ..Default::default()
        },
        RTPCodecType::Video,
    )?;

    // 注册视频：H264-medium
    media_engine.register_codec(
        RTCRtpCodecParameters {
            capability: RTCRtpCodecCapability {
                mime_type: MIME_TYPE_H264.to_owned(),
                clock_rate: 90000,
                channels: 0,
                sdp_fmtp_line: "profile-level-id=4d001f;level-asymmetry-allowed=1;packetization-mode=1".to_owned(),
                rtcp_feedback: vec![],
            },
            payload_type: 103,
            ..Default::default()
        },
        RTPCodecType::Video,
    )?;

    // 注册视频：H264-high
    media_engine.register_codec(
        RTCRtpCodecParameters {
            capability: RTCRtpCodecCapability {
                mime_type: MIME_TYPE_H264.to_owned(),
                clock_rate: 90000,
                channels: 0,
                sdp_fmtp_line: "profile-level-id=64001f;level-asymmetry-allowed=1;packetization-mode=1".to_owned(),
                rtcp_feedback: vec![],
            },
            payload_type: 104,
            ..Default::default()
        },
        RTPCodecType::Video,
    )?;
    // media_engine.register_default_codecs().unwrap();

    let peer_config = RTCConfiguration{
        ice_servers: ice_servers,
        ..Default::default()
    };

    let api = APIBuilder::new()
        .with_media_engine(media_engine)
        .build();

    let peer_connection = api.new_peer_connection(peer_config).await.unwrap();

    // 分离音频和视频, 并将音频和视频发送到指定的IP和端口
    // 生成sdp文件
    divide_audio_video(&peer_connection).await;

    // 音频只接收
    peer_connection.add_transceiver_from_kind(RTPCodecType::Audio, Some(RTCRtpTransceiverInit{
        direction: RTCRtpTransceiverDirection::Recvonly,
        send_encodings: vec![],
    })).await.unwrap();

    // 视频只接收
    peer_connection.add_transceiver_from_kind(RTPCodecType::Video, Some(RTCRtpTransceiverInit{
        direction: RTCRtpTransceiverDirection::Recvonly,
        send_encodings: vec![],
    })).await.unwrap();

    // 设置4个数据通道
    let channel_config = RTCDataChannelInit {
        ordered: Some(true),
        protocol: Some("1.0".to_string()),
        ..Default::default()
    };
    let input_channel = peer_connection.create_data_channel("input", Some(channel_config)).await.unwrap();
    let mut channel_config = RTCDataChannelInit {
        protocol: Some("chatV1".to_string()),
        ..Default::default()
    };
    let chat_channel = peer_connection.create_data_channel("chat", Some(channel_config.clone())).await.unwrap();
    channel_config.protocol = Some("controlV1".to_string());
    let control_channel = peer_connection.create_data_channel("control", Some(channel_config.clone())).await.unwrap();
    channel_config.protocol = Some("messageV1".to_string());
    let message_channel = peer_connection.create_data_channel("message", Some(channel_config)).await.unwrap();


    // 设置本地的sdp
    let sdp_offer = peer_connection.create_offer(None).await.unwrap();
    let sdp_str = sdp_offer.sdp;

    // 临时暂停码率设置
    // // 清除所有现有的 b=AS: 行，然后重新插入
    // let mut new_sdp_lines: Vec<String> = sdp_str.lines()
    //     .filter(|line| !line.starts_with("b=AS:"))
    //     .map(|s| s.to_string())
    //     .collect();

    // // 找到 m=video 和 m=audio 的位置，在其后插入码率行
    // for i in 0..new_sdp_lines.len() {
    //     if new_sdp_lines[i].starts_with("m=video") {
    //         let code = format!("b=AS:{}\r", code_rate::get_video_code_rate().await);
    //         new_sdp_lines.insert(i + 1, code);
    //     }
    //     if new_sdp_lines[i].starts_with("m=audio") {
    //         let code = format!("b=AS:{}\r", code_rate::get_audio_code_rate().await);
    //         new_sdp_lines.insert(i + 1, code);
    //     }
    // }
    // let sdp_str = new_sdp_lines.join("\n");


    // println!("SDP Offer:\n{}", sdp_str);
    // let sdp_offer = RTCSessionDescription::offer(sdp_str.clone()).unwrap();
    peer_connection.set_local_description(peer_connection.create_offer(None).await.unwrap()).await.unwrap();

    
    send_sdp(sdp_str).await.unwrap();

    println!("SDP sent to server");
    // 等待两秒, 为了确保服务器已经收到SDP
    sleep(TokioDuration::from_secs(2)).await;
    let mut remote_sdp = String::new();
    // 最大尝试次数10
    let max_time:u8 = u8::MAX;
    let mut count:u8 = 0;
    loop {
        if let Ok(sdp) = get_sdp().await {
            remote_sdp = sdp;
            println!("Got remote SDP from server");
            break;
        } else {
            // 等待500毫秒, 再次尝试获取SDP
            sleep(TokioDuration::from_millis(500)).await;
            count += 1;
            println!("Retrying to get remote SDP... attempt {}/{}", count, max_time);
            if(count >= max_time) {
                return Err(anyhow!("Failed to get SDP from server"));
            }
        }
    }
    
    let remote_description = RTCSessionDescription::answer(remote_sdp).unwrap();
    peer_connection.set_remote_description(remote_description).await.unwrap();

    println!("SDP exchange completed");
    // 监听ice_candidate事件
    // 查看本地可用的IP和端口
    let ice_candidates = Arc::new(Mutex::new(Vec::<RTCIceCandidate>::new()));
    let candidates_clone = Arc::clone(&ice_candidates);
    peer_connection.on_ice_candidate(Box::new(move |candidate: Option<RTCIceCandidate>| {
        let candidates_clone = candidates_clone.clone();
        Box::pin(async move{
            if let Some(c) = candidate {
                println!("ICE 候选发现: {:?}", c);
                let mut cache = candidates_clone.lock().await;
                cache.push(c.clone());
            }
        })
    }));

    // 发送ice_candidate
    // 发送本地可用的IP和端口
    send_ice(ice_candidates.lock().await.clone()).await.unwrap();

    // 设置远程ICECandidates
    loop {
        let ice_status = get_ice(&peer_connection).await;
        if(ice_status.is_ok()) {
            break;
        }
        sleep(TokioDuration::from_millis(500)).await;
    }
    

    // 阻塞在检查状态上
    check_status::check_status(&peer_connection).await;

    let input_channel_status = INPUT_CHANNEL_STATUS.clone();
    let control_channel_status = CONTROL_CHANNEL_STATUS.clone();
    // 设置通道状态, 允许使用线程通信通道互斥锁
    input_channel_status.store(true, Ordering::SeqCst);
    control_channel_status.store(true, Ordering::SeqCst);

    println!("并发进行初始化");
    // 并发进行初始化
    tokio::join!(
        // 4个通道(chat通道没用到)
        control_channel_init(control_channel), 
        message_channel_init(message_channel),
        input_channel_init(input_channel),

        // // 分离音频和视频, 并将音频和视频发送到指定的IP和端口
        // // 生成sdp文件
        // divide_audio_video(&peer_connection),

        // 检查音频和视频轨道状态
        // 只有在轨道都开启完成的时候才有sdp文件
        check_tracks_status()
    );
    println!("Channels and media division initialized");

    // divide_audio_video(&peer_connection).await;

    // 播放
    media_ctrl::play().await;

    // 将连接设置为静态
    // 方便对连接进行释放
    let mut global_peer_conn = PEER_CONNECTION.lock().await;
    *global_peer_conn = Some(peer_connection);

    // 检测xbox端是否主动断开连接, 如果断开连接则接收端启动关闭会话进程
    close_by_xbox_init().await;

    println!("WebRTC init finished");
    return Ok(());
}